/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package base;

import java.io.IOException;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Paulo
 */
public class ScriptLoader implements AssetLoader {
    private static final ScriptEngineManager engineManager = new ScriptEngineManager();
    private static final String ENGINE_NAME = "JavaScript";
    
    public static ScriptEngine getEngine() {
        return engineManager.getEngineByName(ENGINE_NAME);
    }
    
    public static Invocable readScript(InputStream stream) throws IOException {
        InputStreamReader reader = new InputStreamReader(stream);
        ScriptEngine engine = getEngine();
        Invocable invocable = null;
        
        try {
            engine.eval(reader);
            invocable = (Invocable) engine;
        } catch (ScriptException ex) {
            Logger.getLogger(ScriptLoader.class.getName()).log(Level.SEVERE, "Erro de parsing", ex);
        } finally {
            reader.close();
        }
        return invocable;
    }
    
    public static <T> T getValueOrDefault(ScriptEngine script, String name, T defVal) {
        T value = (T) script.get(name);
        if (value != null) {
            return value;
        } else {
            return defVal;
        }
    }
    
    public static <T> T invokeFunctionOrDefault(Invocable script, String function, T defVal, Object... args) {
        try {
            return (T) script.invokeFunction(function, args);
        } catch (ScriptException ex) {
            return defVal;
        } catch (NoSuchMethodException ex) {
            return defVal;
        }
    }
    
    public static <T> T getInterface(InputStream stream, Class<T> clasz, String referenceCall) throws IOException {
        Invocable invocable = readScript(stream);
        try {
            Object reference = ((ScriptEngine) invocable).eval(referenceCall);
            return invocable.getInterface(reference, clasz);
        } catch (ScriptException ex) {
            Logger.getLogger(ScriptLoader.class.getName()).log(Level.SEVERE, "Erro de parsing", ex);
        }
        
        return null;
    }

    public Object load(AssetInfo assetInfo) throws IOException {
        return readScript(assetInfo.openStream());
    }
}
